package net.cyndeline.stateEvaluation

import net.cyndeline.itemEventFactory.ActionInput
import net.cyndeline.entitySystem.EntityRef

/**
 * Evaluates property conditions on a set of entities, and returns
 * the ones the fulfill the conditions, based on the junction they
 * were added with.
 * 
 * @see net.cyndeline.itemEventFactory.conditions.PropertyCondition
 */
trait Evaluator {
  
  /**
   * Adds a set of property conditions to the evaluator. All conditions added
   * using AND will be stored in the same set, while every set of OR added
   * will become its own disjunction. Any conditions meant to be evaluated
   * using the same OR must all be added using the same set.
   * 
   * @param conditions A set of conditions to be evaluated.
   * @param junction AND if the condition set must all evaluate to true,
   * 				 OR if only one or more conditions must validate.
   */
  def addConditions(conditions: Set[PropertyCondition], junction: Junction)
  
  /**
   * Checks if every condition and evaluator validates.
   * 
   * @param data All entities that should be evaluated.
   * @return Some set of entities the fulfills all evaluated condition sets, or
   * 		 the empty set if no such entities are present.
   */
  def evaluate(data: ActionInput): Set[EntityRef]

}

sealed trait Junction
case object AND extends Junction
case object OR extends Junction
case object AND_OR extends Junction